package com.example.demo.config;

import com.example.demo.entity.Account;
import com.example.demo.entity.Card;
import com.example.demo.keygen.HashCodeKeyGenerator;
import com.example.demo.listener.LoggerListener;
import com.example.demo.mask.IdNumberMaskProcessor;
import com.example.demo.tenant.TenantIdFactory;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.core.FlexGlobalConfig;
import com.mybatisflex.core.keygen.KeyGeneratorFactory;
import com.mybatisflex.core.keygen.KeyGenerators;
import com.mybatisflex.core.keygen.impl.SnowFlakeIDKeyGenerator;
import com.mybatisflex.core.logicdelete.LogicDeleteManager;
import com.mybatisflex.core.logicdelete.impl.IntegerLogicDeleteProcessor;
import com.mybatisflex.core.mask.MaskManager;
import com.mybatisflex.core.mybatis.FlexConfiguration;
import com.mybatisflex.core.tenant.TenantManager;
import com.mybatisflex.spring.boot.ConfigurationCustomizer;
import com.mybatisflex.spring.boot.MyBatisFlexCustomizer;
import com.mybatisflex.spring.boot.SqlSessionFactoryBeanCustomizer;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;

import javax.crypto.KeyGenerator;
import java.security.Key;

@Configuration // 扫描mapper接口所在的包
@MapperScan("com.example.demo.mapper")
public class MybatisFlexConfig implements
        ConfigurationCustomizer,
        SqlSessionFactoryBeanCustomizer, MyBatisFlexCustomizer {
    @Override
    public void customize(FlexConfiguration flexConfiguration) {
        // 控制台显示日志
        flexConfiguration.setLogImpl(StdOutImpl.class);
        System.out.println("Mybatis Configuration 配置：");
    }

    @Override
    public void customize(SqlSessionFactoryBean sqlSessionFactoryBean) {
        System.out.println("SqlSessionFactoryBean 配置：");
    }

    @Override
    public void customize(FlexGlobalConfig globalConfig) {
        System.out.println("Mybatis Flex配置：");
        // 全局配置监听器
        LoggerListener loggerListener = new LoggerListener();
        globalConfig.registerInsertListener(loggerListener, Account.class, Card.class);
        globalConfig.registerUpdateListener(loggerListener, Account.class, Card.class);

        // Order // 全局配置id，实体类也可以重新配，不影响，比如Account
        FlexGlobalConfig.KeyConfig keyConfig = new FlexGlobalConfig.KeyConfig();
        keyConfig.setKeyType(KeyType.Generator);
        keyConfig.setValue(KeyGenerators.flexId);
        keyConfig.setBefore(true);
        globalConfig.setKeyConfig(keyConfig);

        // 自定义主键生成器
        KeyGeneratorFactory.register("hashcode", new HashCodeKeyGenerator());
        // 雪花算法，分布式会用到 // 覆盖 KeyGenerators.snowFlakeId 加入地址等等生成
        KeyGeneratorFactory.register(KeyGenerators.snowFlakeId, new SnowFlakeIDKeyGenerator(1, 1));

        // 逻辑删除值自定义设置
        // 默认0
        globalConfig.setNormalValueOfLogicDelete(0);
        // 默认1
        globalConfig.setDeletedValueOfLogicDelete(2);

        // 内置逻辑删除处理器 // 设置后上面的0，2设置就没用了！
        LogicDeleteManager.setProcessor(new IntegerLogicDeleteProcessor());

        // 多租户 配置
        TenantManager.setTenantFactory(new TenantIdFactory());

        // 自定义数据脱敏配置
        MaskManager.registerMaskProcessor("idNumber", new IdNumberMaskProcessor());
    }
}
